package test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.controller;

import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;


import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.controller.model.DrawModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.controller.utils.TextAttributeUtil;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.DrawView;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.CircleModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.CirclePointModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.DottedLineModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.LineModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.PathModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.PathXY;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.RectModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.RoundRectTextModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.draw.model.TextModel;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.transmission.AbsTransmission;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.transmission.AbsTransmissionSupport;
import test.my.com.myapplicationtest.zhe_xian_tu_view.DynamicPathView.transmission.AccelerateTransmission;


/**
 * Created by MyPC on 2015/8/8.
 */
public class DrawGraphController implements TextureView.SurfaceTextureListener {

    /* https://github.com/lpy19930103/AndroidLineChart */
    private DrawView drawView;
    private float maxValue, minValue;
    private List<DrawModel> drawModels;
    private int delayTime = 1000;
    private boolean isAvailable;
    private boolean isHasData;
    private boolean isStopDraw;// 是否停止绘画（Activity的onDestroy）
    private ScheduledExecutorService scheduledExecutorService;

    // 业务点在图表中的坐标位置
    private List<PathXY> mBusinessPointList = new ArrayList<>();
    // 点击范围的系数
    private float touchRangeUnit = 50;
    // 纵轴显示数据最大值的宽度
    private float mMaxVerticalValueWidth;
    // 是否显示纵轴数据
    private boolean isShowVerticalData;

    /**
     * 是否显示纵轴数据
     * @param showVerticalData
     */
    public void setShowVerticalData(boolean showVerticalData) {
        isShowVerticalData = showVerticalData;
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                start();
            }
        }
    };

    public DrawGraphController(DrawView drawView) {
        this.drawView = drawView;
        drawView.setSurfaceTextureListener(this);
    }

    public void setData(List<DrawModel> drawModels) {
        this.drawModels = drawModels;
        if (drawModels != null && drawModels.size() > 0) {
            minValue = drawModels.get(0).getPriceY();
        }
        for (DrawModel drawModel : drawModels) {
            float price = drawModel.getPriceY();
            if (maxValue < price) {
                maxValue = price;
            }

            if (minValue > price) {
                minValue = price;
            }
        }

        if (maxValue == minValue) {
            int minScale = (int) minValue;//最小刻度值
            float temp = minValue - minScale;//中位数与最小值差
            maxValue = minValue + temp;//最大值
            minValue = minScale;
        } else {
            float temp = maxValue - minValue;
            maxValue = maxValue + temp;
            minValue = minValue - temp;
        }
        DecimalFormat df = new DecimalFormat("0.00");
        String maxString = df.format(maxValue);
        maxValue = Float.valueOf(maxString);
        String minString = df.format(minValue);
        minValue = Float.valueOf(minString);
        isHasData = true;
        initView();
        setTouchListener();
    }

    /**
     * 初始化view一些基本参数
     */
    private void initView() {
        if (isShowVerticalData) { // 是否显示纵坐标数据宽度
            MaxValueInterpolator maxValueInterpolator = new MaxValueInterpolator();
            mMaxVerticalValueWidth = TextAttributeUtil.getTextWidth(maxValueInterpolator.getInterpolation(maxValue) + "",
                    Constant.TEXT_SIZE * drawView.getWidth());
        } else {
            mMaxVerticalValueWidth = 0;
        }
    }

    /**
     * 设置曲线触摸事件
     */
    private void setTouchListener() {
        drawView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        float tx = event.getX();
                        float ty = event.getY();
                        for (int i = 0; i < mBusinessPointList.size(); i++) {
                            PathXY p = mBusinessPointList.get(i);
                            if (p.getX() - touchRangeUnit < tx && tx < p.getX() + touchRangeUnit &&
                                    p.getY() - touchRangeUnit < ty && ty < p.getY() + touchRangeUnit) {
                                drawPriceValue(drawModels.get(i).getPriceY() + "", p.getX(), p.getY(), v);
                            }
                        }
                        break;
                }
                return false;
            }
        });
    }

    public void setDelayTime(int delayTime) {
        this.delayTime = delayTime;
    }

    public void setIsStopDraw(boolean isStopDraw) {
        this.isStopDraw = isStopDraw;
    }

    /**
     * 画坐标轴
     */
    private void drawCoordinate() {
        //纵轴
        float startX, startY, endX, endY;
        startX = CalculateValue.getStartVerticalX(drawView, mMaxVerticalValueWidth);// 从上向下画
        startY = CalculateValue.getStartVerticalY(drawView);
        endX = startX;
        endY = CalculateValue.getEndVerticalY(drawView);
        LineModel lineModel = new LineModel(startX, startY, endX, endY, Constant.LINE_COLOR, 3);
        drawView.drawLine(lineModel);
//     横轴
        float hX, hY;
        hX = CalculateValue.getEndHorizontalX(drawView);
        hY = endY;
        LineModel hLin = new LineModel(endX, endY, hX, hY, Constant.LINE_COLOR, 3);
        drawView.drawLine(hLin);

    }

    /**
     * 画表格横向线
     */
    private void drawTableHorizontalLine() {
        List<LineModel> list = CalculateValue.getTableHorizontalLineModels(drawView, mMaxVerticalValueWidth);
        for (LineModel lineModel : list) {
            drawView.drawLine(lineModel);
        }
    }

    /**
     * 画表格竖向线
     */
    private void drawTableVerticalLine() {
        List<LineModel> list = CalculateValue.getTableVerticalModels(drawView, mMaxVerticalValueWidth);
        for (LineModel lineModel : list) {
            drawView.drawLine(lineModel);
        }
    }

    /**
     * 画浅蓝色填充表格矩形
     */
    private void fillTableColor() {
        List<RectModel> list = CalculateValue.getTableFillRectModels(drawView, mMaxVerticalValueWidth);
        for (RectModel rectModel : list) {
            drawView.drawRect(rectModel);
        }
    }


    /**
     * 绘制折线上的收益
     *
     * @param price
     * @param px
     * @param py
     * @param view
     */
    private void drawPriceValue(String price, float px, float py, View view) {
        float width = TextAttributeUtil.getTextWidth(price, Constant.TEXT_SIZE * view.getWidth());
        float height = TextAttributeUtil.getTextHeight(Constant.TEXT_SIZE * view.getWidth());

        RoundRectTextModel roundRectTextModel = new RoundRectTextModel(px, py - 40, 10, width, height,
                price, Color.WHITE, Constant.TEXT_SIZE * view.getWidth(), Color.parseColor("#F05A4A"));

        CirclePointModel circlePointModel = new CirclePointModel(px, py, 13, 7, Color.parseColor("#F05A4A"), Color.WHITE);

        drawView.getNewCanvas();
        drawTuBiao();
        drawView.drawRoundRectText(roundRectTextModel);
        drawView.drawCirclePoint(circlePointModel);
        drawView.drawNewFinish();
    }

    /**
     * 折线动画后，末尾显示收益
     *
     * @param dotsList
     * @param pointList
     * @param view
     */
    private void drawEndCirclePoint(List<PathXY> dotsList, List<PathXY> pointList, View view) {
        if (dotsList.get(dotsList.size() - 1).getX() == pointList.get(pointList.size() - 1).getX()
                && dotsList.get(dotsList.size() - 1).getY() == pointList.get(pointList.size() - 1).getY()) {
            String price = drawModels.get(drawModels.size() - 1).getPriceY() + "";
            float px = pointList.get(pointList.size() - 1).getX();
            float py = pointList.get(pointList.size() - 1).getY();
            float width = TextAttributeUtil.getTextWidth(price, Constant.TEXT_SIZE * view.getWidth());
            float height = TextAttributeUtil.getTextHeight(Constant.TEXT_SIZE * view.getWidth());

            RoundRectTextModel roundRectTextModel = new RoundRectTextModel(px, py - 40, 10, width, height,
                    price, Color.WHITE, Constant.TEXT_SIZE * view.getWidth(), Color.parseColor("#F05A4A"));

            CirclePointModel circlePointModel = new CirclePointModel(px, py, 13, 7, Color.parseColor("#F05A4A"), Color.WHITE);

            drawView.drawRoundRectText(roundRectTextModel);
            drawView.drawCirclePoint(circlePointModel);
        }

    }

    /**
     * 绘制最终图标
     */
    private void drawTuBiao() {
        final List<PathXY> pathXYList = CalculateValue.getPathList(drawModels, drawView, minValue, maxValue,mMaxVerticalValueWidth);
        PathModel pathModel1 = CalculateValue.getPathModels(pathXYList, drawView, false);
        drawCoordinate();
        drawTableHorizontalLine();
        drawTableVerticalLine();
        fillTableColor();
        drawTimeText(drawModels);
        drawPath(pathModel1);//path不填充
    }


    //画刻度对应的值
    private void drawScaleValue() {
        List<TextModel> list = Calculate.getScaleTextModel(drawView, minValue, maxValue);
        for (TextModel textModel : list) {
            drawView.drawText(textModel);
        }
    }

    //画虚线
    private void drawDashed() {
        List<DottedLineModel> list = Calculate.getDashedModel(drawView, maxValue);
        for (DottedLineModel dottedLineModel : list) {
            drawView.drawDottedLine(dottedLineModel);
        }
    }

    //画横坐标对应文本
    private void drawTimeText(List<DrawModel> list) {
        List<TextModel> textModels = CalculateValue.getTimeTextModels(list, drawView, mMaxVerticalValueWidth);
        for (TextModel textModel : textModels) {
            drawView.drawText(textModel);
        }
    }

    //画对应显示的数值
    private void drawValueText(List<PathXY> valueList, List<DrawModel> drawModelList) {
        List<TextModel> textModels = Calculate.getValueTextModel(valueList, drawModelList, drawView, maxValue);
        for (TextModel textModel : textModels) {
            drawView.drawText(textModel);
        }
    }

    //画点
    private void drawDotsByPathXY(List<PathXY> list) {
        List<CirclePointModel> circlePointModelList = Calculate.getCirclePointListByPathXY(list, drawView, maxValue);
        drawView.drawCirclePoints(circlePointModelList);
    }

    //画Path
    private void drawPath(PathModel pathModel) {
        drawView.drawPath(pathModel);
    }

    //画横坐标刻度
    private void drawHorizontalScale(List<DrawModel> list) {
        List<LineModel> lineModels = Calculate.getHorizontalScale(list, drawView, maxValue);
        for (LineModel lineModel : lineModels) {
            drawView.drawLine(lineModel);
        }
    }

    /**
     * 开始动态绘制
     */
    private void start() {
        final List<PathXY> pathXYList = CalculateValue.getPathList(drawModels, drawView, minValue, maxValue,mMaxVerticalValueWidth);
        final List<PathXY> pointList = CalculateValue.getPointModelList(drawModels, drawView, minValue, maxValue,mMaxVerticalValueWidth);
        final List<PathXY> showValuePathList = Calculate.getShowValuePathList(mBusinessPointList);
        final List<DrawModel> showValueModelList = Calculate.getShowValueModelList(drawModels);
        mBusinessPointList.addAll(pointList);
        AbsTransmission absTransmission = new AccelerateTransmission();
        absTransmission.transmission(new AbsTransmissionSupport<PathXY>() {
            @Override
            public List<PathXY> getTotalAtomic() {
                return pathXYList;
            }

            @Override
            public int getDuration() {
                return delayTime;
            }

            @Override
            public void go(List<PathXY> atomics) {
                if (!isStopDraw) {
                    drawView.getCanvas();
                    List<PathXY> list1 = new ArrayList<PathXY>(atomics);
                    List<PathXY> dotsList = CalculateValue.getDotsList(list1, pointList);
                    List<PathXY> valueList = CalculateValue.getDotsList(list1, showValuePathList);
                    PathModel pathModel1 = CalculateValue.getPathModels(list1, drawView, false);
//                        PathModel pathModel = CalculateValue.getPathModels(list1, drawView, true);
                    drawCoordinate();
                    drawTableHorizontalLine();
                    drawTableVerticalLine();
                    fillTableColor();
                    drawTimeText(drawModels);
                    drawPath(pathModel1);//path不填充
                    drawEndCirclePoint(dotsList, pointList, drawView);
//                    drawScaleValue();
//                        drawDashed();
//                        DrawPath(pathModel);//path填充
//                        drawDotsByPathXY(bitmap, dotsList);
//                        drawDotsByPathXY(dotsList);
//                        drawValueText(valueList,showValueModelList);
//                        drawHorizontalScale(drawModels);
                    drawView.drawFinish();
                }
            }
        });
    }

    /**
     * 防止数据延时
     */
    private void startTimer() {
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                if (isHasData && isAvailable) {
                    handler.sendEmptyMessage(0);
                    scheduledExecutorService.shutdown();
                }
            }
        }, 1, 1, TimeUnit.SECONDS);
    }


    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        isAvailable = true;
        if (isHasData) {
            start();
        } else {
            startTimer();
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

    }
}
